#include "Query_Preprocessor.h"
#include <vector>
#include <string>
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <algorithm>
#include <stdio.h>

Query_Preprocessor::Query_Preprocessor()
{
	
	};
/** Create Mapping
   * 
   * @param The variable type, all the variable of that type, result vector and indepedent result vector
   * @ adds variables to the entity table and intializes result vector and indepedent vector
   */
void Query_Preprocessor::createMapping(int variableType, vector<string>& variableName, struct Result& result,struct Result& independentResult)
{
	vector <int> tempResult;
	if(variableType==_PROGLINE)
	{
		variableType = _STMT;
	}

	for(unsigned int j=0;j<variableName.size();j++)
	{
		if(variableType==_PROGLINE)
		{

			result.resultVector[_STMT].resultEntity.push_back(tempResult);
			independentResult.resultVector[_STMT].resultEntity.push_back(tempResult);

		}
		else
		{

			result.resultVector[variableType].resultEntity.push_back(tempResult);
			independentResult.resultVector[variableType].resultEntity.push_back(tempResult);
			if(entityTableMapping[variableType][0].compare("0")==0)
				entityTableMapping[variableType][0] = variableName[0];
			else
				entityTableMapping[variableType].push_back(variableName[j]);
		}
	}

};

/** Create Entity Table
   * 
   * @ Initializes the entity table
   */
void Query_Preprocessor::createEntityTable()
{
	entityTable.push_back("assign");
	entityTable.push_back("call");
	entityTable.push_back("if");
	entityTable.push_back("while");
	entityTable.push_back("procedure");
	entityTable.push_back("stmtLst");
	entityTable.push_back("stmt");
	entityTable.push_back("variable");
	entityTable.push_back("constant");
	entityTable.push_back("INTEGER");
	entityTable.push_back("Synonyms");
	vector<string> init;


	init.push_back("0");

	for(unsigned int i =0;i<entityTable.size();i++)
	{
		entityTableMapping.push_back(init);
	}
	vector<string> initAttrName;
	vector<int> initAttrNameMapping;
	vector<int> initDependencyList;
	for(unsigned int i =0;i<entityTable.size();i++)
	{
		attrName.push_back(initAttrName);
		attrNameMapping.push_back(initAttrNameMapping);
		dependencyList.push_back(initDependencyList);
	
	}
	attrName[_VARIABLE].push_back("varName");
	attrNameMapping[_VARIABLE].push_back(_VARNAME);
	attrName[_STMT].push_back("stmt#");
	attrNameMapping[_STMT].push_back(_STMTNO);
	attrName[_STMT].push_back("prog_line#");
	attrNameMapping[_STMT].push_back(_STMTNO);
	attrName[_PROCEDURE].push_back("procName");
	attrNameMapping[_PROCEDURE].push_back(_PROCNAME);
	attrName[_CONSTANT].push_back("value");
	attrNameMapping[_CONSTANT].push_back(_CONSTANTVALUE);
	attrName[_IF].push_back("stmt#");
	attrNameMapping[_IF].push_back(_STMTNO);
	attrName[_WHILE].push_back("stmt#");
	attrNameMapping[_WHILE].push_back(_STMTNO);
	attrName[_CALL].push_back("stmt#");
	attrNameMapping[_CALL].push_back(_STMTNO);
	attrName[_ASSIGN].push_back("stmt#");
	attrNameMapping[_ASSIGN].push_back(_STMTNO);
	attrName[_CALL].push_back("procName");
	attrNameMapping[_CALL].push_back(_PROCNAME);



	/*for(int i=0;i<entityTable.size();i++)
	{
	cout <<i<<" "<<entityTable[i]<<endl;
	}*/

};

/** Create Entity  Relationship Table
   * 
   * @ Initializes the entity relationship table
   */
void Query_Preprocessor::createEntityRelTable()
{

	RelationshipTable.push_back("Follows");
	RelationshipTable.push_back("Parent");
	
	RelationshipTable.push_back("Modifies");
	RelationshipTable.push_back("Uses");
	RelationshipTable.push_back("Calls");
	RelationshipTable.push_back("Calls*");
	RelationshipTable.push_back("Next");
	RelationshipTable.push_back("Follows*");
	RelationshipTable.push_back("Parent*");
	RelationshipTable.push_back("Next*");
	RelationshipTable.push_back("Affects");
	RelationshipTable.push_back("Affects*");

	NoOfArguments.push_back(2);
	NoOfArguments.push_back(2);
	NoOfArguments.push_back(2);
	NoOfArguments.push_back(2);
	NoOfArguments.push_back(2);
	NoOfArguments.push_back(2);
	NoOfArguments.push_back(2);
	NoOfArguments.push_back(2);
	NoOfArguments.push_back(2);
	NoOfArguments.push_back(2);
	NoOfArguments.push_back(2);
	NoOfArguments.push_back(2);

	//Follows Arguments

	arg1Follows.push_back(_ASSIGN);
	arg1Follows.push_back(_CALL);
	arg1Follows.push_back(_IF);
	arg1Follows.push_back(_WHILE);
	arg1Follows.push_back(_STMT);
	arg1Follows.push_back(_INTEGER);
	arg1Follows.push_back(_UNDERSCORE);


	arg2Follows.push_back(_ASSIGN);
	arg2Follows.push_back(_CALL);
	arg2Follows.push_back(_IF);
	arg2Follows.push_back(_WHILE);
	arg2Follows.push_back(_STMT);
	arg2Follows.push_back(_INTEGER);
	arg2Follows.push_back(_UNDERSCORE);







	// Follows* Arguments

	arg1FollowsT.push_back(_ASSIGN);
	arg1FollowsT.push_back(_CALL);
	arg1FollowsT.push_back(_IF);
	arg1FollowsT.push_back(_WHILE);
	arg1FollowsT.push_back(_STMT);
	arg1FollowsT.push_back(_INTEGER);
	arg1FollowsT.push_back(_UNDERSCORE);


	arg2FollowsT.push_back(_ASSIGN);
	arg2FollowsT.push_back(_CALL);
	arg2FollowsT.push_back(_IF);
	arg2FollowsT.push_back(_WHILE);
	arg2FollowsT.push_back(_STMT);
	arg2FollowsT.push_back(_INTEGER);
	arg2FollowsT.push_back(_UNDERSCORE);

	//Parent Arguments


	arg1Parent.push_back(_ASSIGN);
	arg1Parent.push_back(_CALL);
	arg1Parent.push_back(_IF);
	arg1Parent.push_back(_WHILE);
	arg1Parent.push_back(_STMT);
	arg1Parent.push_back(_INTEGER);
	arg1Parent.push_back(_UNDERSCORE);

	arg2Parent.push_back(_ASSIGN);
	arg2Parent.push_back(_CALL);
	arg2Parent.push_back(_IF);
	arg2Parent.push_back(_WHILE);
	arg2Parent.push_back(_STMT);
	arg2Parent.push_back(_INTEGER);
	arg2Parent.push_back(_UNDERSCORE);







	// Parent* Arguments

	arg1ParentT.push_back(_ASSIGN);
	arg1ParentT.push_back(_CALL);
	arg1ParentT.push_back(_IF);
	arg1ParentT.push_back(_WHILE);
	arg1ParentT.push_back(_STMT);
	arg1ParentT.push_back(_INTEGER);
	arg1ParentT.push_back(_UNDERSCORE);

	arg2ParentT.push_back(_ASSIGN);
	arg2ParentT.push_back(_CALL);
	arg2ParentT.push_back(_IF);
	arg2ParentT.push_back(_WHILE);
	arg2ParentT.push_back(_STMT);
	arg2ParentT.push_back(_INTEGER);
	arg2ParentT.push_back(_UNDERSCORE);

	// Modifies Arguments

	arg1Modifies.push_back(_ASSIGN);
	arg1Modifies.push_back(_CALL);
	arg1Modifies.push_back(_IF);
	arg1Modifies.push_back(_WHILE);
	arg1Modifies.push_back(_PROCEDURE);
	arg1Modifies.push_back(_STMT);
	arg1Modifies.push_back(_INTEGER);


	arg2Modifies.push_back(_VARIABLE);
	arg2Modifies.push_back(_UNDERSCORE);



	//Uses Arguments

	arg1Uses.push_back(_ASSIGN);
	arg1Uses.push_back(_CALL);
	arg1Uses.push_back(_IF);
	arg1Uses.push_back(_WHILE);
	arg1Uses.push_back(_PROCEDURE);
	arg1Uses.push_back(_STMT);
	arg1Uses.push_back(_INTEGER);


	arg2Uses.push_back(_VARIABLE);
	arg2Uses.push_back(_UNDERSCORE);

	//Calls Argument

	arg1Call.push_back(_PROCEDURE);
	arg1Call.push_back(_UNDERSCORE);


	arg2Call.push_back(_PROCEDURE);
	arg2Call.push_back(_UNDERSCORE);




	//Calls* Arguments
	arg1CallT.push_back(_PROCEDURE);
	arg1CallT.push_back(_UNDERSCORE);


	arg2CallT.push_back(_PROCEDURE);
	arg2CallT.push_back(_UNDERSCORE);
	//Next Arguments
	arg1Next.push_back(_ASSIGN);
	arg1Next.push_back(_CALL);
	arg1Next.push_back(_IF);
	arg1Next.push_back(_WHILE);
	arg1Next.push_back(_STMT);
	arg1Next.push_back(_INTEGER);
	arg1Next.push_back(_UNDERSCORE);

	arg2Next.push_back(_ASSIGN);
	arg2Next.push_back(_CALL);
	arg2Next.push_back(_IF);
	arg2Next.push_back(_WHILE);
	arg2Next.push_back(_STMT);
	arg2Next.push_back(_INTEGER);
	arg2Next.push_back(_UNDERSCORE);

	//NextT Arguments
	arg1NextT.push_back(_ASSIGN);
	arg1NextT.push_back(_CALL);
	arg1NextT.push_back(_IF);
	arg1NextT.push_back(_WHILE);
	arg1NextT.push_back(_STMT);
	arg1NextT.push_back(_INTEGER);
	arg1NextT.push_back(_UNDERSCORE);

	arg2NextT.push_back(_ASSIGN);
	arg2NextT.push_back(_CALL);
	arg2NextT.push_back(_IF);
	arg2NextT.push_back(_WHILE);
	arg2NextT.push_back(_STMT);
	arg2NextT.push_back(_INTEGER);
	arg2NextT.push_back(_UNDERSCORE);

	//Affects Arguments
	arg1Affects.push_back(_ASSIGN);
	arg1Affects.push_back(_STMT);
	arg1Affects.push_back(_INTEGER);
	arg1Affects.push_back(_UNDERSCORE);

	arg2Affects.push_back(_ASSIGN);
	arg2Affects.push_back(_STMT);
	arg2Affects.push_back(_INTEGER);
	arg2Affects.push_back(_UNDERSCORE);

	//AffectsT Arguments
	arg1AffectsT.push_back(_ASSIGN);
	arg1AffectsT.push_back(_STMT);
	arg1AffectsT.push_back(_INTEGER);
	arg1AffectsT.push_back(_UNDERSCORE);

	arg2AffectsT.push_back(_ASSIGN);
	arg2AffectsT.push_back(_STMT);
	arg2AffectsT.push_back(_INTEGER);
	arg2AffectsT.push_back(_UNDERSCORE);

};

/** Check Relationship Arguments Validity
   * 
   * @param the arguments of the clause and the relationship for that clause
   * @return Returns true if the arguments are valid for the relationship and false if they are invalid
   */
bool Query_Preprocessor::checkRelationshipArgumentsValidity(int arg1Index,int arg2Index,int relationshipIndex)
{

	if(relationshipIndex==FOLLOWS)
	{
		if((binary_search(arg1Follows.begin(),arg1Follows.end(),arg1Index)) && (binary_search(arg2Follows.begin(),arg2Follows.end(),arg2Index)))
		{
			return true;
		}
	}
	if(relationshipIndex==FOLLOWST)
	{
		if((binary_search(arg1FollowsT.begin(),arg1FollowsT.end(),arg1Index)) && (binary_search(arg2FollowsT.begin(),arg2FollowsT.end(),arg2Index)))
		{
			return true;
		}
	}
	if(relationshipIndex==MODIFIES)
	{
		if((binary_search(arg1Modifies.begin(),arg1Modifies.end(),arg1Index)) && (binary_search(arg2Modifies.begin(),arg2Modifies.end(),arg2Index)))
		{
			return true;
		}
	}
	if(relationshipIndex==USES)
	{
		if((binary_search(arg1Uses.begin(),arg1Uses.end(),arg1Index)) && (binary_search(arg2Uses.begin(),arg2Uses.end(),arg2Index)))
		{
			return true;
		}
	}
	if(relationshipIndex==PARENT)
	{
		if((binary_search(arg1Parent.begin(),arg1Parent.end(),arg1Index)) && (binary_search(arg2Parent.begin(),arg2Parent.end(),arg2Index)))
		{
			return true;
		}
	}
	if(relationshipIndex==PARENTT)
	{
		if((binary_search(arg1ParentT.begin(),arg1ParentT.end(),arg1Index)) && (binary_search(arg2ParentT.begin(),arg2ParentT.end(),arg2Index)))
		{
			return true;
		}
	}
	if(relationshipIndex==CALLS)
	{
		if((binary_search(arg1Call.begin(),arg1Call.end(),arg1Index)) && (binary_search(arg2Call.begin(),arg2Call.end(),arg2Index)))
		{
			return true;
		}
	}
	if(relationshipIndex==CALLST)
	{
		if((binary_search(arg1CallT.begin(),arg1CallT.end(),arg1Index)) && (binary_search(arg2CallT.begin(),arg2CallT.end(),arg2Index)))
		{
			return true;
		}
	}
	if(relationshipIndex==NEXT)
	{
		if((binary_search(arg1Next.begin(),arg1Next.end(),arg1Index)) && (binary_search(arg2Next.begin(),arg2Next.end(),arg2Index)))
		{
			return true;
		}
	}
	if(relationshipIndex==NEXTT)
	{
		if((binary_search(arg1NextT.begin(),arg1NextT.end(),arg1Index)) && (binary_search(arg2NextT.begin(),arg2NextT.end(),arg2Index)))
		{
			return true;
		}
	}
	if(relationshipIndex==AFFECTS)
	{
		if((binary_search(arg1Affects.begin(),arg1Affects.end(),arg1Index)) && (binary_search(arg2Affects.begin(),arg2Affects.end(),arg2Index)))
		{
			return true;
		}
	}
	if(relationshipIndex==AFFECTST)
	{
		if((binary_search(arg1AffectsT.begin(),arg1AffectsT.end(),arg1Index)) && (binary_search(arg2AffectsT.begin(),arg2AffectsT.end(),arg2Index)))
		{
			return true;
		}
	}
	return false;
};


/** Create Query tree
   * 
   * @param query string, the vectors for pattern, such that and with, and the result vector
   * @Scans the query and puts the clauses in the appropriate vectors
   */
int Query_Preprocessor::createQueryTree(string s,vector<suchThatClause>& suchThat,struct Result& result,vector<withClause>& with,vector<patternClause>& pattern)
{
	suchThat.clear();
	//result.clear();
	with.clear();
	pattern.clear();
	result.selectedType.clear();
	result.resultIndex.clear();
	result.resultAtrributeType.clear();
	independentList.clear();
	for(unsigned int i=0;i<dependencyList.size();i++)
		dependencyList[i].clear();
	Result tempResult;
	suchThatClause tempSuchThat;
	withClause tempWith;
	Argument tempArgument;
	patternClause tempPattern;
	int relationshipIndex;
	int entityIndex;

	char * tmp ;
	char *str;
	int noOfCompoundQueries = 0;
	bool curr = false;
	bool validClause = false;
	bool queryResult = true;
	string queryArgument = "";
	bool andClause = false;
	tmp = new char [s.size()+1];
	strcpy(tmp,s.c_str());
	str = strtok(tmp," ");
	if(str==NULL)
	{
		cout<<"Invalid Query Format: Use Select (design-entity) clauses";
		return -1;
	}
	queryArgument = str;


	if(boost::iequals(queryArgument,"select")!=1)
	{
		cout<<"Invalid Query Format: Use Select (design-entity) clauses";
		return -1;
	}
	str = strtok(NULL," ");
	if(str==NULL)
	{
		cout<<"Invalid Query Format: Use Select (design-entity) clauses";
		return -1;
	}
	string entity = str;
	int entityType = -1;
	int argInd = 0;
	if(boost::iequals(str,"boolean")==1)
	{
		entityIndex = _BOOLEAN;
		result.selectedType.push_back((QRYSTATEMENT_TYPE)entityIndex);
	}
	else
	{
		if(str[0]=='<')
		{
			entity = str;
			string tupleString = entity;
			while(entity[entity.size()-1]!='>')
			{
				str = strtok(NULL," ");
				if(str==NULL)
					return -1;
				entity = str;

				tupleString = tupleString + " " + entity;


			}
			entity = tupleString;
			if(entity[entity.size()-1]!='>')
				return -1;
			vector<string> tokens;
			tokenize(tokens,entity,"<,>");
			if(tokens.size()==0)
				return -1;
			for(unsigned int u=0;u<tokens.size();u++)
			{
			string attrString =  tokens[u];
			vector<string> elementTokens;
			boost::trim(attrString);
			tokenize(elementTokens,attrString,".");
			entityIndex = getEntityIndex(elementTokens.front(),entityType,argInd);
			if(entityIndex<0||entityType!=ARGUMENT)
			{
				cout<<"Invalid Entity. Please check if you have declared entity"<<elementTokens.front();
				return -1;
			}
			dependencyList[entityIndex].push_back(argInd);
			if(elementTokens.size()>2)
				return -1;
			if(elementTokens.size()==2)
			{
				attrString = elementTokens[1];
				int attrName;
				attrName =  checkAttributeName(entityIndex,attrString);
				if(attrName <0)
				{
					cout<<"Invalid attribute:"<<attrString;
					return -1;
				}
				result.resultAtrributeType.push_back((WITHATTRIBUTE_TYPE)attrName);
			}
			else
			{
				result.resultAtrributeType.push_back((WITHATTRIBUTE_TYPE)(attrNameMapping[entityIndex][0]));

			}
			result.selectedType.push_back((QRYSTATEMENT_TYPE)entityIndex);
			result.resultIndex.push_back(argInd);
			elementTokens.clear();
			}
					

		}
		else
		{
			vector<string> tokens;
			string attrString =  entity;
			tokens.clear();
			tokenize(tokens,attrString,".");
			entityIndex = getEntityIndex(tokens.front(),entityType,argInd);
			if(entityIndex<0)
			{
				cout<<"Invalid Entity. Please check if you have declared entity"<<tokens.front();
				return -1;
			}
			if(tokens.size()>2)
				return -1;
			if(tokens.size()==2)
			{
				attrString = tokens[1];
				int attrName;
				attrName = checkAttributeName(entityIndex,attrString);
				if(attrName<0)
				{
					cout<<"Invalid attribute:"<<attrString;
					return -1;
				}
				result.resultAtrributeType.push_back((WITHATTRIBUTE_TYPE)attrName);

			}
			else
			{
				result.resultAtrributeType.push_back((WITHATTRIBUTE_TYPE)attrNameMapping[entityIndex][0]);
			}
			dependencyList[entityIndex].push_back(argInd);
			result.selectedType.push_back((QRYSTATEMENT_TYPE)entityIndex);
			result.resultIndex.push_back(argInd);
		}
	}



	str = strtok(NULL," ");
	while(str!=NULL)
	{
		if((boost::iequals(str,"such")==1)||((boost::iequals(str,"and")==1)&&(curr)))
		{
			curr = true;
			validClause = true;
			if(boost::iequals(str,"such")==1)
			{
				str = strtok(NULL," ");
				if(str==NULL||boost::iequals(str,"that")!=1)
				{
					cout<<"Invalid clause: Expected \"such that\"";
					return -1;
				}
			}
			else
			{
				andClause = true;
			}


			tempSuchThat.arguments.clear();
			str = strtok(NULL," ");
			if(str==NULL)
			{
				if(andClause)
				{
					cout<<"Invalid clause type";
				}
				else
				{
					cout<<"Invalid arguments format. Please use [relationship](arg1, arg2)";
				}
				return -1;
			}
			entity = str;
			vector<string> tokens;
			tokenize(tokens,entity,"(");
			

			string relationship = tokens.front();

			if(relationship[relationship.size()-1]==' ')
				relationship.pop_back();

			relationshipIndex = getRelationshipIndex(relationship);
			if(relationshipIndex<0)
			{

				if(andClause)
				{
					queryResult = false;
				}
				else
				{
					return -1;
					cout<<"Invalid relationship type.";
				}
			}
			if(queryResult)
			{
				if(tokens.size()<2)
				 {
					str = strtok(NULL," ");
				 if(str==NULL)
				{
					cout<<"Expected (arg1, arg2)";
					return -1;
				} 
				 entity = str;
				 if(entity[0]!='(')
				 {
					 cout<<"Expected (arg1, arg2)";
					 return -1;
				 }
				 vector<string> tokens;
				 if(entity.size()>1)
				 {
                 
			     tokenize(tokens,entity,"(");
				 entity = tokens[0];
				 }
				 else
				 {
					 str = strtok(NULL," ");
				 if(str==NULL)
				{
					cout<<"Expected (arg1, arg2)";
					return -1;
				} 
				  entity = str;
				 }
				}
				else
				{
					entity = tokens[1];
				}
				
			string suchThatString = entity;
			int numCount = 1;
			while(entity[entity.size()-1]!=')')
			{
				str = strtok(NULL," ");
				if(str==NULL)
				{
					cout<<"Unknown symbol at the end of query";
					return -1;
				}
				entity = str;

				suchThatString = suchThatString + " " + entity;


			}

			entity = suchThatString;
			
				tempSuchThat.relationshipType = relationshipIndex;
				tokens.clear();
				tokenize(tokens,entity,",");
				if(tokens.size()<2)
				{
					cout<<"Invalid arguments format. Please use [relationship](arg1, arg2)"; 
					return -1;
				}
				entity = tokens.front();
				string tempArg1;
				if(entity[0]==' ')
				{
					if(entity[entity.size()-1]==' ')
					{
						string tempArg(entity.begin()+1,entity.end()-1);
						tempArg1 = tempArg;
					}
					else
					{
						string tempArg(entity.begin()+1,entity.end());
						tempArg1 = tempArg;
					}
				}
				else if(entity.size()-1==' ')
				{
					string tempArg(entity.begin(),entity.end()-1);
					tempArg1 = tempArg;
				}
				else
				{
					tempArg1 = tokens[0];
				}
				int argInd = -1;
				if(tempArg1.compare("_")==0)
				{
					entityIndex = _UNDERSCORE;
					entityType = ARGUMENT;
					argInd = -1;

				}
				else
				{
					if(tempSuchThat.relationshipType==MODIFIES||tempSuchThat.relationshipType==CALLS||tempSuchThat.relationshipType==USES||tempSuchThat.relationshipType==CALLST)
					{
						entityType = PROCARGUMENT;
					}
					boost::trim(tempArg1);
						entityIndex = getEntityIndex(tempArg1,entityType,argInd);
				}

				if(entityIndex<0)
				{
					if(entityIndex==-1)
					{
						cout<<"Invalid entity type. Please check if you have declared the entity "<<tempArg1;
					}
					else
					{
						return -2;
					}
					return -1;
				}
				if(entityType==INTARGUMENT)
				{
					int intValidity = checkIntArgument(entityIndex,_STMT);
					if(intValidity<0)
					{
						return -2;
					}
				}
				tempArgument.argument = entityIndex;
				tempArgument.argumentType = entityType;
				tempArgument.argumentInd = argInd;
				tempSuchThat.arguments.push_back(tempArgument);
				entity = tokens[1];
				tokens.clear();
				string tempArg2;
				if(entity[0]==' ')
				{
					if(entity[entity.size()-2]==' ')
					{
						string tempArg(entity.begin()+1,entity.end()-2);
						tempArg2 = tempArg;
					}
					else
					{
						string tempArg(entity.begin()+1,entity.end()-1);
						tempArg2 = tempArg;
					}
				}
				else if(entity.size()-2==' ')
				{
					string tempArg(entity.begin(),entity.end()-2);
					tempArg2 = tempArg;
				}
				else
				{
					string tempArg(entity.begin(),entity.end()-1);
					tempArg2 = tempArg;
				}

				entityType = -1;
				argInd = -1;
				if(tempArg2.compare("_")==0)
				{
					entityIndex = _UNDERSCORE;
					entityType = ARGUMENT;
					argInd = -1;

				}
				else
				{
					if(tempSuchThat.relationshipType==MODIFIES||tempSuchThat.relationshipType==USES)
					{
						entityType = VARARGUMENT;
					}
					if(tempSuchThat.relationshipType==CALLS||tempSuchThat.relationshipType==CALLST)
					{
						entityType = PROCARGUMENT;
					}
					boost::trim(tempArg2);
					entityIndex = getEntityIndex(tempArg2,entityType,argInd);
				}

				if(entityIndex<0)
				{
					if(entityIndex==-1)
					{
						cout<<"Invalid entity type. Please check if you have declared the entity "<< tempArg2;
					}
					else
					{
						return -2;
					}
					return -1;
				}
				if(entityType==INTARGUMENT)
				{
					int intValidity = checkIntArgument(entityIndex,_STMT);
					if(intValidity<0)
					{
						return -2;
					}
				}
				//arguments = entityIndex;
				tempArgument.argument = entityIndex;
				tempArgument.argumentType = entityType;
				tempArgument.argumentInd = argInd;
				tempSuchThat.arguments.push_back(tempArgument);
				int independence = checkIndependence(result.selectedType,tempSuchThat.arguments[0],tempSuchThat.arguments[1]);
				tempSuchThat.index = independence;
				suchThat.push_back(tempSuchThat);
				int tempArgument1= tempSuchThat.arguments[0].argument;
				int tempArgument2= tempSuchThat.arguments[1].argument;
				if(tempSuchThat.arguments[0].argumentType==INTARGUMENT)
				{
					tempArgument1 = _INTEGER;
				}
				if(tempSuchThat.arguments[1].argumentType==INTARGUMENT)
				{
					tempArgument2 = _INTEGER;
				}
				if(tempSuchThat.arguments[0].argumentType==VARARGUMENT)
				{
					tempArgument1 = _VARIABLE;
				}
				if(tempSuchThat.arguments[1].argumentType==VARARGUMENT)
				{
					tempArgument2 = _VARIABLE;
				}
				if(tempSuchThat.arguments[0].argumentType==PROCARGUMENT)
				{
					tempArgument1 = _PROCEDURE;
				}
				if(tempSuchThat.arguments[1].argumentType==PROCARGUMENT)
				{
					tempArgument2 = _PROCEDURE;
				}

				if(!checkRelationshipArgumentsValidity(tempArgument1,tempArgument2,relationshipIndex))
				{
					cout<<"Invalid arguments. Please ensure the arguments match the relationship "<<RelationshipTable[relationshipIndex];
					return -1;
				}



			}

		}

		if((boost::iequals(str,"with")==1)||(andClause&&(curr)&&!queryResult))
		{

			queryResult = true;
			curr = true;
			validClause = true;
			if(!andClause)
			{
				str = strtok(NULL," ");
			}

			tempWith.arguments.clear();



			if(str==NULL)
			{
				cout<<"Invalid with type. Expected Arguments";
				return -1;
			}
			entity = str;

			int argInd = -1;
			vector<string> tokensEqual;
			tokenize(tokensEqual,entity,"=");
			entity = tokensEqual.front();
			vector<string> tokensDot;
			tokenize(tokensDot,entity,".");
			entityIndex = getEntityIndex(tokensDot.front(),entityType,argInd);
			if(entityIndex<0)
			   {
				if(andClause)
				{
					queryResult = false;
				}
				else
				{
					return -1;
				}
			}
			if(tokensDot.size()<2)
			{
				if(andClause)
				{
					queryResult = false;
				}
				else
				{
					return -1;
				}
			}
			
			if(queryResult)
			{
			queryResult = true;
			string tmpAttrCondition = tokensDot[1];
			int res = checkAttributeName(entityIndex,tmpAttrCondition);
			if(res<0)
			{
				cout<<"Invalid Attribute. Please use the approriate attribute and attribute Name";
				return -1;
			}
			tempArgument.withAttribute = res;
			if(entityIndex<0||entityType!=ARGUMENT)
			{
				if(entityIndex==-1||entityType!=ARGUMENT)
				{
					cout<<"Invalid entity type. Please check if you have declared the entity "<<entity;
				}
				return -1;
			}
			tempArgument.argument = entityIndex;

			
			
				tempArgument.argumentInd = argInd;
				tempArgument.argumentType = entityType;
				tempWith.arguments.push_back(tempArgument);
			    
			
			
			if(tokensEqual.size()<2)
			{

				str = strtok(NULL," ");
				tokensEqual.clear();
				entity = str;
				tokenize(tokensEqual,entity,"=");
				if((tokensEqual.size()!=1)&&(entity.compare("=")!=0))
				{
					cout<<"Invalid Comparison: Expected \"=\"";
					return -1;
				}
				else if((entity.compare("=")==0))
				{
					str = strtok(NULL," ");
					tmpAttrCondition = str;

				}
				else
				{
					tmpAttrCondition = tokensEqual.front();
				}
			}
			else
			{
				tmpAttrCondition = tokensEqual[1];
			}


			tokensEqual.clear();
			
			if(tmpAttrCondition[tmpAttrCondition.size()-1]!='\"' && isdigit(tmpAttrCondition[tmpAttrCondition.size()-1])==0)
				tempWith.withType = _COMPARISON;
			else
				tempWith.withType = _VALUE;
			tokensDot.clear();
			tokenize(tokensDot,tmpAttrCondition,".");
			entity = tokensDot.front();
			argInd = -1;
			
			if(tempWith.arguments[0].argument==_PROCEDURE||tempWith.arguments[0].argument==_CALL)
			{
				entityType = PROCARGUMENT;
			entityIndex = getEntityIndex(entity,entityType,argInd);
			}
			else if(tempWith.arguments[0].argument==_VARIABLE)
			{
				entityType = VARARGUMENT;
			entityIndex = getEntityIndex(entity,entityType,argInd);
			}
			else
			{
			entityIndex = getEntityIndex(entity,entityType,argInd);
			}
			if(entityIndex<0)
			{
				if(entityIndex==-1)
				{
					cout<<"Invalid entity type. Please check if you have declared the entity "<<entity;
				}
				else
				{
					return -2;
				}
				return -1;
			}
			if(entityType==INTARGUMENT)
			{
				int intValidity = checkIntArgument(entityIndex,tempArgument.argument);
				if(intValidity<0)
				{
					return -2;
				}
			}
	
			
			
			if(tempWith.withType==_COMPARISON)
			{
				if(entityType!=ARGUMENT)
					return -1;
				if(tokensDot.size()<2)
					return -1;
				tmpAttrCondition = tokensDot[1];
				int res = checkAttributeName(entityIndex,tmpAttrCondition);
				if(res<0)
				{
					cout<<"Invalid Attribute. Please use the approriate attribute and attribute Name";
					return -1;
				}
				tempArgument.withAttribute = res;
				
			}
			else
			{
				tempArgument.withAttribute = -1;
			}
			if(tokensDot.size()>2)
				return -1;
			tempArgument.argument = entityIndex;
			tempArgument.argumentType = entityType;
			tempArgument.argumentInd = argInd;
			
			tempWith.arguments.push_back(tempArgument);
			res = checkAttributeCompatibility(tempWith.arguments[0],tempWith.arguments[1]);
			if(res<0)
			{
				cout<<"Invalid attribute comparison. Please use attributes of the same type";
				return -1;
			}
			if(tempWith.withType==_VALUE)
			{
				if(tempWith.arguments[0].argument==_CALL&&tempWith.arguments[0].withAttribute==_PROCNAME)
				{
					vector<int> callResult;
					queryObj.getCallStmt(callResult,tempWith.arguments[1].argument);
					if(callResult.size()>0)
						tempWith.arguments[1].argument = callResult[0];
					else
						return -1;
				}
			}
			with.push_back(tempWith);	
			if(tempWith.withType==_COMPARISON)
			{
            int temp = checkIndependence(result.selectedType,tempWith.arguments[0],tempWith.arguments[1]);
			}
		}
	}
	if((boost::iequals(str,"pattern")==1)||queryResult==false)
	{
		int underscoreCount = 0;
		curr = true;
		validClause = true;
		queryResult = true;
		tempPattern.arguments.clear();
		if(andClause==false||(boost::iequals(str,"pattern")==1))
		{
		str = strtok(NULL," ");
		if(str==NULL)
		{
			cout<<"Expected Design Entity";
			return -1;
		}
		}
		entity = str;
		string patternString = entity;
		while(entity[entity.size()-1]!=')')
			{
				str = strtok(NULL," ");
				if(str==NULL)
					return -1;
				entity = str;

				patternString = patternString + " " + entity;


			}

		entity = patternString;
		vector<string> tokens;
		tokenize(tokens,entity,"(");
		if(tokens.size()<2)
			return -1;
		entity = tokens.front();
		if(entity[entity.size()-1]==' ')
			entity.pop_back();
		entityIndex = getEntityIndex(entity,entityType,argInd);
		if((entityIndex<0)||(!((entityIndex==_WHILE)||(entityIndex==_IF)||(entityIndex==_ASSIGN))))
		{
			if(entityIndex==-1||entityType!=ARGUMENT)
			{
				cout<<"Invalid entity type";
			}
			return -1;
		}

		tempArgument.argument = entityIndex;
		tempArgument.argumentInd = argInd;
		tempArgument.argumentType = entityType;
		tempPattern.arguments.push_back(tempArgument);
		
		
		entity = tokens[1];
		tokens.clear();
		tokenize(tokens,entity,"," );
			if(tokens.size()>3)
				return -1;
        entity = tokens.front();
		string tempArg2;
				if(entity[0]==' ')
				{
					if(entity[entity.size()-1]==' ')
					{
						string tempArg(entity.begin()+1,entity.end()-1);
						tempArg2 = tempArg;
					}
					else
					{
						string tempArg(entity.begin()+1,entity.end());
						tempArg2 = tempArg;
					}
				}
				else if(entity.size()-1==' ')
				{
					string tempArg(entity.begin(),entity.end());
					tempArg2 = tempArg;
				}
				else
				{
					string tempArg(entity.begin(),entity.end());
					tempArg2 = tempArg;
				}

		string tempArg = tempArg2;
		
		if(tempArg.compare("_")==0)
		{
			tempArgument.argument = _UNDERSCORE;
			tempArgument.argumentInd = argInd;
			tempArgument.argumentType = ARGUMENT;
			tempPattern.arguments.push_back(tempArgument);
		}
		else
		{
			entityType = VARARGUMENT;
			entityIndex = getEntityIndex(tempArg,entityType,argInd);
			if(entityIndex<0)
			{ 
				cout<<"Invalid entity. Please check if you have declared entity"<<tempArg;
				return -1;
			}
			if(entityType==VARARGUMENT||entityIndex==_VARIABLE)
			{
			tempArgument.argument = entityIndex;
			tempArgument.argumentInd = argInd;
			tempArgument.argumentType = entityType;
			tempPattern.arguments.push_back(tempArgument);
			checkIndependence(result.selectedType,tempPattern.arguments[0],tempPattern.arguments[1]);
			}
			else
			{
				cout<<"Invalid entity. Please use only entity of variable type";
				return -1;
			}

		}
		
		

		if(tempPattern.arguments[0].argument==_ASSIGN)
		{
			if(tokens.size()>2)
				return -1;
			entity = tokens[1];
			string tempArg2;
				if(entity[0]==' ')
				{
					if(entity[entity.size()-2]==' ')
					{
						string tempArg(entity.begin()+1,entity.end()-2);
						tempArg2 = tempArg;
					}
					else
					{
						string tempArg(entity.begin()+1,entity.end()-1);
						tempArg2 = tempArg;
					}
				}
				else if(entity.size()-2==' ')
				{
					string tempArg(entity.begin(),entity.end()-2);
					tempArg2 = tempArg;
				}
				else
				{
					string tempArg(entity.begin(),entity.end()-1);
					tempArg2 = tempArg;
				}
				entity = tempArg2;
			if(entity[0]=='_')
			{
				underscoreCount++;

				if(entity.size()<2)
				{
					
						tempPattern.stringArgument.argumentType = ARGUMENT;
						tempPattern.stringArgument.position = PATTERN_mid;
						tempPattern.stringArgument.stringArgument = "_";
						pattern.push_back(tempPattern);
				}


				else 
				{
					if(entity[1]!='\"')
						return -1;
					string tempArg1(entity.begin()+2,entity.end());
					entity = tempArg1;
					string expString = tempArg1;
					
					if(entity[entity.size()-1]=='\"')
					{
						expString.pop_back();
						int valRes = validateExpression(expString);
					    if(valRes==-1)
						{
					    cout<<"Invalid expression "<<expString;
						return -1;
						}
						tempPattern.stringArgument.argumentType = STRINGARGUMENT;
						tempPattern.stringArgument.position = PATTERN_end;
						tempPattern.stringArgument.stringArgument = expString;
						pattern.push_back(tempPattern);

					}
					else if((entity[entity.size()-2]=='\"')&&entity[entity.size()-1]=='_')
					{
						expString.pop_back();
						expString.pop_back();
						int valRes = validateExpression(expString);
					    if(valRes==-1)
						{
						cout<<"Invalid expression "<<expString;
						return -1;
						}
						tempPattern.stringArgument.argumentType = STRINGARGUMENT;
						tempPattern.stringArgument.position = PATTERN_mid;
						tempPattern.stringArgument.stringArgument = expString;
						pattern.push_back(tempPattern);
					}
					else
					{
						return -1;
					}
				}

			}
			else if(entity[0]=='\"')
			{
				string tempArg1(entity.begin()+1,entity.end());
				entity = tempArg1;
				string expString = entity;
				
				if(entity[entity.size()-1]=='\"')
				{
					expString.pop_back();
					int valRes = validateExpression(expString);
				    if(valRes==-1)
					{
						cout<<"Invalid expression "<<expString;
						return -1;
					}
					tempPattern.stringArgument.argumentType = STRINGARGUMENT;
					tempPattern.stringArgument.position = PATTERN_entire;
					tempPattern.stringArgument.stringArgument = expString;
					pattern.push_back(tempPattern);

				}
				else if((entity[entity.size()-2]=='\"')&&entity[entity.size()-1]=='_')
				{
					expString.pop_back();
					expString.pop_back();
					int valRes = validateExpression(expString);
				    if(valRes==-1)
					{
						cout<<"Invalid expression "<<expString;
						return -1;
					}
					tempPattern.stringArgument.argumentType = STRINGARGUMENT;
					tempPattern.stringArgument.position = PATTERN_begin;
					tempPattern.stringArgument.stringArgument = expString;
					pattern.push_back(tempPattern);

				}
				else
				{
					return -1;
				}
			}
		}

		else
		{
			if(tempPattern.arguments[0].argument==_IF)
			{
				if(tokens.size()!=3)
				{
					return -1;
				}
				entity = tokens[1];
				boost::trim(entity);
				if(entity[0]!='_')
					return -1;
				tempArgument.argument = _UNDERSCORE;
				tempArgument.argumentInd = argInd;
				tempArgument.argumentType = ARGUMENT;
				tempPattern.arguments.push_back(tempArgument);
				pattern.push_back(tempPattern);
				entity = tokens[2];
				boost::trim(entity);
				if(entity[0]!='_')
					return -1;

			}
			else
			{
				if(tokens.size()!=2)
				{
					return -1;
				}

				entity = tokens[1];
				boost::trim(entity);
				if(entity[0]!='_')
					return -1;
				tempArgument.argument = _UNDERSCORE;
				tempArgument.argumentInd = argInd;
				tempArgument.argumentType = ARGUMENT;
				tempPattern.arguments.push_back(tempArgument);
				pattern.push_back(tempPattern);
			}
		}


	}

	if(!queryResult||validClause==false)
	{
		cout<<"Invalid clause";
		return -1;
	}
	andClause=false;
	queryResult = true;
	validClause = false;
	str = strtok(NULL," ");
	noOfCompoundQueries++;
}
for(unsigned int j=0;j<suchThat.size();j++)
{
	int ind = checkIndependence(result.selectedType,suchThat[j].arguments[0],suchThat[j].arguments[1]);
	suchThat[j].index = ind;
}   
return 1;
};

/** Create Entity Relationship Table
   * 
   * @param Relatinoship string
   * @return Returns the relationship index if it exists else returns -1
   */
int Query_Preprocessor::getRelationshipIndex(string Relationship)
{

	for(unsigned int i =0;i<RelationshipTable.size();i++)
	{
		if(boost::iequals(RelationshipTable[i],Relationship)==1)
			return i;
	}
	return -1;


};

/** Get Entity Index
   * 
   * @param entity variable name, variable type, variable argument index
   * @return Returns the variable type, variable index and variable argument index. return <0 if variable doesnt exist 
   */
int Query_Preprocessor::getEntityIndex(string entity,int &entityType,int &entityInd)
{
	int Number = 0;
	vector<string> tempName;
	if(entity[0]=='\"')
	{
		tokenize(tempName,entity,"\"");
		if(tempName.size()==0)
		{

			return -1;
		}

		boost::trim(tempName.front());
		Number = queryObj.getEntityTypeIndex(tempName.front(),entityType);
		if(Number>=0)
		{
			return Number;
		}
		else
		{
			return -2;
		}
	}
	else
	{
		if((Number=isNumber(entity))<0)
		{
			for(unsigned int i =0;i<entityTableMapping.size();i++)
			{
				for(unsigned int j=0;j<entityTableMapping[i].size();j++)
				{
					if(entityTableMapping[i][j].compare(entity)==0)
					{
						entityType = ARGUMENT;
						entityInd = j;

						return i;
					}
				}
			}
		}
		else
		{
			entityType = INTARGUMENT;

			return  Number;

		}
	}
	return -1;


};

int Query_Preprocessor::isNumber(string temp)
{
	int returnValue = -1;
	if(temp.compare("0")==0)
	{
		return 0;
	}
	for(unsigned int i = 0; i < temp.length(); i++) {

		if(isdigit(temp[i]))
		{
			returnValue = 1;
		}
		else
		{
			returnValue = -1;
			break;
		}

	}
	if(returnValue==1)
	{
		returnValue =  atoi(&temp[0]);

	}
	return returnValue;
};
int Query_Preprocessor::checkIntArgument(int argument, int argType)
{
	int result = queryObj.validateEntity(argument,argType);

	return result;
};

/** Check Atrribute Name
   * 
   * @param with argument index, atrribute name, 
   * @return Returns the with attribute type if it is valid else return -1
   */
int Query_Preprocessor::checkAttributeName(int attrIndex,string atrName)
{
	for(unsigned int i=0;i<attrName[attrIndex].size();i++)
	{
	if(boost::iequals(attrName[attrIndex][i],atrName)==1)
	{
		return attrNameMapping[attrIndex][i];
	}
	}
	return -1;
}
int Query_Preprocessor::tokenize(vector<string>& tokens,const string& str,const string& delimiters)

{


	// skip delimiters at beginning.
	string::size_type lastPos = str.find_first_not_of(delimiters, 0);

	// find first "non-delimiter".
	string::size_type pos = str.find_first_of(delimiters, lastPos);

	while (string::npos != pos || string::npos != lastPos)
	{
		// found a token, add it to the vector.
		tokens.push_back(str.substr(lastPos, pos - lastPos));

		// skip delimiters.  Note the "not_of"
		lastPos = str.find_first_not_of(delimiters, pos);

		// find next "non-delimiter"
		pos = str.find_first_of(delimiters, lastPos);
	}

	return 1;
};

/** Get check attribute compatibility
   * 
   * @param with arguments of the with query 
   * @return Returns 1 if it is valid else return -1
   */
int Query_Preprocessor::checkAttributeCompatibility(Argument &argument1,Argument &argument2)
{
	
	int arg1 = argument1.withAttribute;
	int arg2 = argument2.withAttribute;
	if(arg1==arg2)
	{
		return 1;
	}
	if((arg1==_PROCNAME&& arg2==_VARNAME) ||(arg2==_PROCNAME && arg1==_VARNAME))
	{
		return 1;
	}
	if((arg1==_STMTNO && arg2==_CONSTANTVALUE)||(arg2==_STMTNO && arg1==_CONSTANTVALUE))
	{
		return 1;
	}
	if((arg1==_PROGLINE && arg2==_CONSTANTVALUE)||(arg2==_PROGLINE && arg1==_CONSTANTVALUE))
	{
		return 1;
	}
	if((arg1==_STMTNO && arg2==_PROGLINE)||(arg2==_STMTNO && arg1==_PROGLINE))
	{
		return 1;
	}
	arg1 = argument1.argument;
	arg2 = argument2.argumentType;
	if(arg1==arg2)
	{
		return 1;
	}
	if((arg1==_PROCEDURE&& arg2==PROCARGUMENT) ||(arg1==_CALL && arg2==PROCARGUMENT))
	{
		return 1;
	}
	if(arg1==_VARIABLE&& arg2==VARARGUMENT)
	{
		return 1;
	}
	if((arg1==_STMT|| arg1==_ASSIGN||(arg1==_CALL) ||(arg1==_CONSTANT)||arg1==_IF||arg1==_WHILE)&&arg2==INTARGUMENT)
	{
		return 1;
	}
	
	return -1;



};

/** Check Independence
   * 
   * @param result types in the query and the two arguments in the current query 
   * @return checks if the arguments are dependent on the current dependency list. If yes return -1 else return 1.
   */
int Query_Preprocessor::checkIndependence(vector<QRYSTATEMENT_TYPE> &resultType,Argument &argument1,Argument &argument2)
{
	if(resultType[0]==_BOOLEAN)
	{
		return 1;

	}
	if(argument1.argument!=_UNDERSCORE&&argument1.argumentType==ARGUMENT)
	{
	for(unsigned int i=0;i<dependencyList[argument1.argument].size();i++)
	{
			if(argument1.argumentInd==dependencyList[argument1.argument][i])
			{
				if(argument2.argument!=_UNDERSCORE&&argument2.argumentType==ARGUMENT)
				{
					dependencyList[argument2.argument].push_back(argument2.argumentInd);
				    updateDependencyList(argument2);
				}

				return -1;
			}
	}
	}
	if(argument2.argument!=_UNDERSCORE&&argument2.argumentType==ARGUMENT)
	{
	for(unsigned int i=0;i<dependencyList[argument2.argument].size();i++)
	{
			if(argument2.argumentInd==dependencyList[argument2.argument][i])
			{
				if(argument1.argument!=_UNDERSCORE&&argument1.argumentType==ARGUMENT)
					dependencyList[argument1.argument].push_back(argument1.argumentInd);
				    updateDependencyList(argument1);
				return -1;
			}
	}
	}
	independentNodes tempIndependentNodes;
	Argument tempArgument;
	if(argument2.argument!=_UNDERSCORE&&argument2.argumentType==ARGUMENT&&argument1.argument!=_UNDERSCORE&&argument1.argumentType==ARGUMENT)
	{
		tempArgument.argument = argument1.argument;
		tempArgument.argumentInd = argument1.argumentInd;
		tempIndependentNodes.arguments.push_back(tempArgument);
		tempArgument.argument = argument2.argument;
		tempArgument.argumentInd = argument2.argumentInd;
		tempIndependentNodes.arguments.push_back(tempArgument);
	}
	else if(argument2.argument!=_UNDERSCORE&&argument2.argumentType==ARGUMENT)
	{
		tempArgument.argument = argument2.argument;
		tempArgument.argumentInd = argument2.argumentInd;
		tempIndependentNodes.arguments.push_back(tempArgument);

	}
	else
	{
		tempArgument.argument = argument1.argument;
		tempArgument.argumentInd = argument1.argumentInd;
		tempIndependentNodes.arguments.push_back(tempArgument);
	}
	independentList.push_back(tempIndependentNodes);

	return 1;

}

/** Update dependency list
   * 
   * @param argument to add to list
   * check independent list and adds to dependency list if the arguments match.
   */
void Query_Preprocessor::updateDependencyList(Argument &dependencyArg)
{
	for(unsigned int i =0;i<independentList.size();i++)
	{
		if((dependencyArg.argument==independentList[i].arguments[0].argument)&&(dependencyArg.argumentInd==independentList[i].arguments[0].argumentInd))
		{
			if(independentList[i].arguments.size()==2)
			{
				dependencyList[independentList[i].arguments[1].argument].push_back(independentList[i].arguments[1].argumentInd);

			}

		}
		else
		{
			if(independentList[i].arguments.size()==2)
			{
			if((dependencyArg.argument==independentList[i].arguments[1].argument)&&(dependencyArg.argumentInd==independentList[i].arguments[1].argumentInd))
			{
			
				dependencyList[independentList[i].arguments[0].argument].push_back(independentList[i].arguments[0].argumentInd);

			

			}
			}

		}
	
	}

};

/** Validate Expression
   * 
   * @param expression of string type
   * @return Validates expression and return 1 if valid and -1 if invalid.
   */
int Query_Preprocessor::validateExpression(string &expression)
{

	int leftBracketCount = 0;
	int previousType = ot_VARIABLE;
	int validateResult = 1;
	int space = 0;
	boost::trim(expression);
	if(expression.size()==0)
	{
	return -1;
	}
	for(unsigned int i =0;i<expression.size();i++)
	{
		if(isalpha(expression[i])!=0)
		{
			
			if((previousType==ot_VARIABLE)||(previousType==ot_OPERATOR))
			{
				if(previousType==ot_VARIABLE)
					if(space==1)
						return -1;
				previousType = ot_VARIABLE;
			}
			else
			{
				return -1;
			}
			space = 0;
		}
		else if(isdigit(expression[i])!=0)
		{
			if(((previousType==ot_NUMBER)||(previousType==ot_OPERATOR))||i==0||(previousType==ot_VARIABLE))
			{
				if(previousType==ot_VARIABLE)
					if(space==1)
						return -1;
				previousType = ot_NUMBER;
			}
			else
			{
				return -1;
			}
			space = 0;
			continue;
		}


		else if(expression[i]=='+'||expression[i]=='-'||expression[i]=='*')
		{
			if(((previousType==ot_VARIABLE)||(previousType==ot_NUMBER))&&(i!=0))
			{
				previousType = ot_OPERATOR;
			}
			else
			{
				return -1;
			}
			space = 0;
			continue;
		}
		else if(expression[i]==' ')
		{
				space = 1;
		}
		else
		{
			return -1;
		}

	}
	return validateResult;
};
